package com.testxmlparse;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.common.collect.Lists;
import com.sun.istack.internal.logging.Logger;

import cn.com.zte.ant.model.AntModelLoader;
import cn.com.zte.ant.model.AntModelObjectPartner;
import cn.com.zte.ant.model.AntUtil;
import cn.com.zte.ant.model.ModelRalationSearcher;
import cn.com.zte.ngbc.frw.model.ModelFileAware;
import cn.com.zte.ngbc.frw.model.ModelObject;
import cn.com.zte.ngbc.frw.model.generator.GeneratorTypeManager;
import cn.com.zte.ngbc.frw.model.generator.ModelJavaGenerator.JavaClassModel;
import cn.com.zte.ngbc.frw.model.generator.ServiceGenerator;
import cn.com.zte.ngbc.frw.model.tran.service.ServiceImplementation;
import cn.com.zte.ngbc.frw.model.util.FileModelFile;
import cn.com.zte.ngbc.frw.model.util.ModelFactoryUtil;
import cn.com.zte.ngbc.frw.model.util.ModelFile;

public class SingleGenerateJava extends ModelRalationSearcher {
	List<ModelFileAware> source_models = Lists.newArrayList();
	private static final Logger log = Logger.getLogger(SingleGenerateJava.class);

	@Test
	public void generateJavaFile(String filepath) throws Exception {
		String baseDir = "";
		// 生成代码---开始D:\j2eeworks\base0317\cm\src\main\resources\servicetype\tell\TlNbXxgl.serviceType.xml
		Set<File> toGenerateFile = new HashSet();
//		toGenerateFile.add(new File(
//				"D:\\j2eeworks\\base0317\\cm\\src\\main\\resources\\servicetype\\tell\\TlNbXxgl.serviceType.xml"));
		toGenerateFile.add(new File(filepath));
		// 获取关联文件
		Set<File> relationFiles = getRelationFiles(toGenerateFile);
		AntModelLoader m = new AntModelLoader(toGenerateFile, relationFiles);
		AntModelObjectPartner.setModelLoader(m);
		for (Object model1 : m.getSourceModels()) {
			ModelFileAware modelFile = (ModelFileAware) model1;
			System.out.println(modelFile.getId());
			baseDir = modelFile.getModelFile().getFullPath();
			GeneratorTypeManager.GeneratorType gt = GeneratorTypeManager.getInstance()
					.getGeneratorType(modelFile.getClass());
			JavaClassModel ret3 = gt.creatJavaClassModelWithoutContent(modelFile);
			String a = gt.getJavaContent(ret3, modelFile);
			log.info("test another way to generate class content");
			log.info(ret3.getClassName() + a);
		}
	}

	/**
	 * 查找并返回依赖文件
	 * 
	 * @throws XPathExpressionException
	 * 
	 * @throws Exception
	 */
	public Set<File> getRelationFiles(Set<File> files) throws XPathExpressionException {
		String relFileName = "";
		Set<File> relationFiles = new HashSet();
		String basePath, serviceTypePath, complexTypePath = "";
		// 解析文件，生成document对象
		DocumentBuilder builder = null;
		Document document = null;
		// 生成XPath对象
		XPath xpath = XPathFactory.newInstance().newXPath();
		// 查找全文件scope属性对应的值
		XPathExpression compile = null;
		try {
			builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		for (File file : files) {
			basePath = file.getPath();
			serviceTypePath = getServiceTypePath(basePath);
			try {
				document = builder.parse(file);
			} catch (SAXException | IOException e) {
				e.printStackTrace();
			}
			if (file.getName().indexOf(".flowtrans.xml") > 0) {
				compile = xpath.compile("//@serviceName");
				NodeList list = (NodeList) compile.evaluate(document, XPathConstants.NODESET);
				for (int i = 0; i < list.getLength(); i++) {
					Node item = list.item(i);
					relFileName = item.getNodeValue();
					String temparr[] = relFileName.split("\\.");
					relFileName = temparr[0];
					relationFiles.add(new File(serviceTypePath + "\\" + relFileName + ".serviceType.xml"));
				}
			} else if (file.getName().indexOf(".serviceType.xml") > 0) {
				compile = xpath.compile("//@type");
				NodeList list = (NodeList) compile.evaluate(document, XPathConstants.NODESET);
				for (int i = 0; i < list.getLength(); i++) {
					Node item = list.item(i);
					relFileName = item.getNodeValue();
					String temparr[] = relFileName.split("\\.");
					if (temparr.length > 1 && !"BaseEnumType".equalsIgnoreCase(temparr[0])
							&& !"BaseType".equalsIgnoreCase(temparr[0])) {
						relFileName = temparr[0];
						if (!relationFiles.contains(serviceTypePath + "\\" + relFileName + ".c_schema.xml"))
							relationFiles.add(new File(serviceTypePath + "\\" + relFileName + ".c_schema.xml"));
					}
				}
			}
		}
		// 添加基础的xml文件
		relationFiles
				.add(new File("D:\\j2eeworks\\base0317\\sys\\src\\main\\resources\\datatype\\BaseType.u_schema.xml"));
		relationFiles.add(
				new File("D:\\j2eeworks\\base0317\\sys\\src\\main\\resources\\datatype\\BaseEnumType.e_schema.xml"));
		return relationFiles;
	}

	private String getServiceTypePath(String basePath) {
		// 根据解析类型转换目录结构
		String path = "";
		if (basePath.indexOf(".flowtrans.xml") > 0) {
			basePath = basePath.replaceAll("trans", "serviceType");
			basePath = basePath.replaceFirst("tran", "");
		}
		if (basePath.indexOf(".serviceType.xml") > 0) {
			basePath = basePath.replaceAll("servicetype", "type");
		}
		int pos = basePath.lastIndexOf("\\");
		path = basePath.substring(0, pos);
		return path;
	}

	public void aname() throws Exception {
		Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

		ModelObject model = ModelFactoryUtil.parse((ModelFile) new FileModelFile(new File(
				"D:\\api\\po\\modules\\busi\\cm\\src\\main\\resources\\serviceimpl\\tell\\TlYcsqServiceImpl.serviceImpl.xml")
		// new
		// File("D:\\api\\po\\modules\\busi\\cm\\src\\main\\resources\\servicetype\\tell\\TlNbMmgl.serviceType.xml")
		));
		ServiceImplementation si = (ServiceImplementation) model;
		JavaClassModel ret = new JavaClassModel(si.getPackage(), si.getId());
		String a = ServiceGenerator.generateJava(ret, model);
		System.out.println(a);
	}

}